home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / HexEdit 1.21 / ~Project / Source / HexSearch.c < prev    next >
Encoding:
Text File  |  1997-08-03  |  7.2 KB  |  323 lines  |  [TEXT/CWIE]

  1. /*********************************************************************
  2.  * HexSearch.c
  3.  *
  4.  * HexEdit, a simple hex editor
  5.  * copyright 1993, Jim Bumgardner
  6.  *
  7.  * LR :changed all "OK"s to 1, "Cancel"s to 2, and "black" to "qd.black"
  8.  *********************************************************************/
  9. // Todo:
  10. //         Disable search buttons if text field is empty
  11.  
  12. #include "HexEdit.h"
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16.  
  17. #define SearchForwardItem    1
  18. #define SearchBackwardItem    2
  19. #define HexModeItem            3
  20. #define AsciiModeItem        4
  21. #define SearchTextItem        5
  22.  
  23. short            gSearchMode = EM_Ascii;
  24. short            gSearchDir = 0;    // 1 = backward
  25. unsigned char    gSearchBuffer[256],gSearchText[256],gGotoText[256];
  26. DialogPtr        gSearchWin;
  27. Boolean StringToSearchBuffer(void);
  28.  
  29. void OpenSearchDialog(void)
  30. {
  31.     // If Dialog Window isn't open
  32.     if (gSearchWin == NULL) {
  33.         // Open Dialog Window
  34.         MySetCursor(C_Arrow);
  35.         gSearchWin = GetNewDialog(SearchDLOG, NULL, (WindowPtr) -1L);
  36.         if (gSearchWin) {
  37.             // Convert Existing Search Scrap, if it exists to text
  38.             SetText(gSearchWin, SearchTextItem, gSearchText);
  39.  
  40.             // Set Radio Buttons
  41.             SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  42.             SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  43.             SelectDialogItemText(gSearchWin, SearchTextItem, 0, 32767);
  44.             ShowWindow(gSearchWin);
  45.         }
  46.     }
  47.     else
  48.         SelectWindow(gSearchWin);
  49. }
  50.  
  51. void PerformTextSearch(EditWindowPtr dWin)
  52. {
  53.     WindowPtr    wp;
  54.     short        ch,matchIdx;
  55.     long        addr,matchAddr;
  56.  
  57.     if (dWin == NULL) {
  58.         // Find and Select Top Window
  59.         wp = FrontWindow();
  60.         while (wp && ((WindowPeek) wp)->refCon != MyWindowID)
  61.             wp = (WindowPtr) ((WindowPeek) wp)->nextWindow;
  62.         if (wp == NULL || ((WindowPeek) wp)->refCon != MyWindowID)
  63.             return;
  64.         dWin = (EditWindowPtr) wp;
  65.     }
  66.  
  67.     MySetCursor(C_Watch);
  68.  
  69.     // Search in Direction gSearchDir
  70.     // for text gSearchBuffer
  71.  
  72.     if (gSearchDir == 0)
  73.         addr = dWin->endSel;
  74.     else {
  75.         addr = dWin->startSel - 1;
  76.         if (addr < 0)
  77.             return;
  78.     }
  79.     matchIdx = 0;
  80.     while (1) {
  81.         ch = GetByte(dWin, addr);
  82.         if (ch == gSearchBuffer[matchIdx+1]) {
  83.             if (matchIdx == 0)
  84.                 matchAddr = addr;
  85.             ++matchIdx;
  86.             if (matchIdx >= gSearchBuffer[0])
  87.                 goto Success;
  88.             ++addr;
  89.             if (addr == dWin->fileSize) {
  90.                 matchIdx = 0;
  91.                 addr = matchAddr;
  92.             }
  93.             else
  94.                 continue;
  95.         }
  96.         else {
  97.             if (matchIdx) {
  98.                 matchIdx = 0;
  99.                 addr = matchAddr;
  100.             }
  101.         }
  102.         if (gSearchDir == 0) {
  103.             ++addr;
  104.             if (addr == dWin->fileSize)
  105.                 goto Failure;
  106.         }
  107.         else {
  108.             --addr;
  109.             if (addr < 0)
  110.                 goto Failure;
  111.         }
  112.     }
  113.  
  114. Failure:
  115.     SysBeep(1);
  116.     MySetCursor(C_Arrow);
  117.     return;
  118.  
  119. Success:
  120.     if (dWin != (EditWindowPtr) FrontWindow())
  121.         SelectWindow((WindowPtr) dWin);
  122.     dWin->startSel = matchAddr;
  123.     dWin->endSel = dWin->startSel + gSearchBuffer[0];
  124.  
  125.     ScrollToSelection(dWin, dWin->startSel, true, true);
  126.     MySetCursor(C_Arrow);
  127. }
  128.  
  129.  
  130. #define GAddrItem            3
  131. #define GHexItem            4
  132. #define GAsciiItem            5
  133. #define GUserItem            6
  134.  
  135. static pascal void GotoUserItem(DialogPtr dp, short itemNbr)
  136. {
  137.     switch (itemNbr) {
  138.     case GUserItem:
  139.         MyOutlineButton(dp, 1, qd.black);
  140.         break;
  141.     }
  142.     
  143. }
  144.  
  145. void GotoAddress(EditWindowPtr dWin)
  146. {
  147.     GrafPtr        savePort;
  148.     DialogPtr    dp;
  149.     short        itemHit;
  150.     short        t;
  151.     Handle        h;
  152.     Rect        r;
  153.  
  154.     GetPort(&savePort);
  155.     MySetCursor(C_Arrow);
  156.     dp = GetNewDialog(GotoDLOG, NULL, (WindowPtr) -1L);
  157.     if (dp == NULL)
  158.         return;
  159.     GetDialogItem(dp, GUserItem, &t, &h, &r);
  160.     SetDialogItem(dp, GUserItem, t, (Handle) GotoUserItem, &r);
  161.  
  162.     SetText(dp, GAddrItem, gGotoText);
  163.     // Set Radio Buttons
  164.     SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  165.     SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  166.     SelectDialogItemText(dp, GAddrItem, 0, 32767);
  167.     ShowWindow(dp);
  168.     do {
  169.         ModalDialog(NULL, &itemHit);
  170.         switch (itemHit) {
  171.         case 1:
  172.             GetText(dp, GAddrItem, gGotoText);
  173.         case 2:
  174.             break;
  175.         case GHexItem:
  176.             gPrefs.decimalAddr = EM_Hex;
  177.             SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  178.             SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  179.             break;
  180.         case GAsciiItem:
  181.             gPrefs.decimalAddr = EM_Ascii;
  182.             SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  183.             SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  184.             break;
  185.         }
  186.     } while (itemHit != 1 && itemHit != 2);
  187.     DisposeDialog(dp);
  188.     SetPort(savePort);
  189.     if (itemHit == 1) {
  190.         long        addr = -1;
  191.         short        r;
  192.  
  193.         PtoCstr(gGotoText);
  194.         if (gPrefs.decimalAddr == EM_Hex)
  195.             r = sscanf((char *) gGotoText,"%lx",&addr);
  196.         else
  197.             r = sscanf((char *) gGotoText,"%ld",&addr);
  198.         CtoPstr((char *) gGotoText);
  199.         if (r == 1 && addr >= 0 && addr < dWin->fileSize) {
  200.             dWin->startSel = dWin->endSel = addr;
  201.             ScrollToSelection(dWin, addr, true, true);
  202.         }
  203.     }
  204. }
  205.  
  206. void DoModelessDialogEvent(EventRecord *theEvent)
  207. {
  208.     DialogPtr    whichDlog;
  209.     short        itemHit;
  210.     // Do Event Filtering
  211.     if (theEvent->what == keyDown) {
  212.         // Process Edit Keys
  213.         if ((theEvent->message & charCodeMask) == '\r') {
  214.             whichDlog = FrontWindow();
  215.             itemHit = 1;
  216.             MySimulateButtonPress(whichDlog, 1);
  217.             goto ButtonHit;
  218.         }
  219.         if (theEvent->modifiers & cmdKey) {
  220.             switch ((theEvent->message & keyCodeMask) >> 8) {
  221.             case 0x0D:    // W
  222.                 DisposeDialog(gSearchWin);
  223.                 gSearchWin = NULL;
  224.                 return;
  225.             case 0x0C:    // Q
  226.                 if (CloseAllEditWindows())
  227.                     gQuitFlag = true;
  228.                 return;
  229.             }
  230.         }
  231.     }
  232.     if(DialogSelect(theEvent, &whichDlog, &itemHit)) {
  233. ButtonHit:
  234.         if (whichDlog == gSearchWin) {
  235.             switch (itemHit) {
  236.             case SearchForwardItem:
  237.             case SearchBackwardItem:
  238.                 gSearchDir = (itemHit == SearchBackwardItem);
  239.                 GetText(gSearchWin, SearchTextItem, gSearchText);
  240.                 if (StringToSearchBuffer()) {
  241.                     PerformTextSearch(NULL);
  242.                 }
  243.                 break;
  244.             case HexModeItem:
  245.                 gSearchMode = EM_Hex;
  246.                 SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  247.                 SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  248.                 break;
  249.             case AsciiModeItem:
  250.                 gSearchMode = EM_Ascii;
  251.                 SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  252.                 SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  253.                 break;
  254.             case SearchTextItem:
  255.                 break;
  256.             }
  257.         }
  258.     }
  259.     else {
  260. /*        switch (theEvent->what) {*/
  261. /*        case updateEvt:*/
  262. /*            MyDoEvent(theEvent);*/
  263. /*            break;*/
  264. /*        }*/
  265.         if (theEvent->what == updateEvt && whichDlog == gSearchWin)
  266.             MyOutlineButton(gSearchWin, SearchForwardItem, qd.black);
  267.     }
  268. }
  269.  
  270. Boolean StringToSearchBuffer(void)
  271. {
  272.     Ptr                sp, dp;
  273.     short            i;
  274.     short            val;
  275.     Boolean            loFlag;
  276.  
  277.     // Convert String to gSearchBuffer
  278.     if (gSearchMode == EM_Hex) {
  279.         sp = (Ptr) &gSearchText[1];
  280.         dp = (Ptr) &gSearchBuffer[1];
  281.         loFlag = false;
  282.         for (i = 0; i < gSearchText[0]; ++i,++sp) {
  283.             if (*sp == '0' && *(sp+1) == 'x') {
  284.                 loFlag = 0;
  285.                 ++sp;
  286.                 ++i;
  287.                 continue;
  288.             }
  289.             if (isspace(*sp) || ispunct(*sp)) {
  290.                 loFlag = 0;
  291.                 continue;
  292.             }
  293.             if (*sp >= '0' && *sp <= '9')
  294.                 val = *sp - '0';
  295.             else if (*sp >= 'A' && *sp <= 'F')
  296.                 val = 0x0A + (*sp - 'A');
  297.             else if (*sp >= 'a' && *sp <= 'f')
  298.                 val = 0x0A + (*sp - 'a');
  299.             else
  300.                 goto HexError;
  301.             if (loFlag) {
  302.                 *(dp-1) = (*(dp-1) << 4) | val;
  303.                 loFlag = 0;
  304.             }            
  305.             else {
  306.                 *dp = val;
  307.                 ++dp;
  308.                 loFlag = 1;
  309.             }
  310.         }
  311.         gSearchBuffer[0] = (long) dp - (long) &gSearchBuffer[1];
  312.         if (gSearchBuffer[0] == 0)
  313.             goto HexError;
  314.     }
  315.     else {
  316.         BlockMove(gSearchText, gSearchBuffer, gSearchText[0]+1);
  317.     }
  318.     return true;
  319. HexError:
  320.     ErrorAlert(ES_Caution, "Only valid Hex values may be used");
  321.     return false;
  322. }
  323.